<?php

namespace app\admin\behavior;

use think\Request;
use think\facade\Session;
use app\common\exception\NoAuthorizeException;
use ReflectionClass;

class AuthorizeFilter
{
    static $authorize_regex="/^@authorize(\('.+'\))?$/i";
    static $authorize_replace="/^@authorize(\('(.+)'\))?$/i";
    static $allow_regex="/^@allow$/i";

    public function run(Request $request, $params)
    {
        
        $items=$params[0];
        $class=new ReflectionClass($items);

        $actionMethod=$class->getMethod($request->action());

        if(!$this->findAtrribute($actionMethod,self::$allow_regex))
        {
            $attribute=$this->findAtrribute($actionMethod,self::$authorize_regex);
            if($attribute)
            {
                if(!$request->user) throw new NoAuthorizeException("未授权",401);
                //在 action上找是否开启了权限
                $this->checkAuthorize($attribute);
                return;
            }

            //如果action上没有设置 检查Controller上找是否开启了权限
            $attribute=$this->findAtrribute($class,self::$authorize_regex);
            if($attribute)
            {
                if(!$request->user) throw new NoAuthorizeException("未授权",401);
                //在 Controller上找是否开启了权限
                $this->checkAuthorize($attribute);
                return;
            }
        }
    }

    /**
     * 找到注释
     *
     * @param [type] $class
     * @param [type] $pattern  正则匹配注释
     * @return void
     */
    private function findAtrribute($class,$pattern){
        $attribute=$class->getDocComment();
        $attribute=explode("*",$attribute);
        $attribute=array_filter($attribute,function($item) use($pattern){
            $item=trim($item);
            if(preg_match($pattern,$item)){
                return true;
            }
           return false;
        });
        if(count($attribute)>0) return trim(array_pop($attribute));
        return null;
    }
    
    /**
     * 判断注释上的权限用户是否拥有
     *
     * @param [type] $attribute
     * @return void
     */
    private function checkAuthorize($attribute){
        if(empty($attribute)) return true;

        $item=$attribute;
        $item=preg_replace(self::$authorize_replace, "$2", $item);
        $ss=request();
        if(empty($item)) return true;

        $permissions=Session::get('permissions'); 
        if(empty($permissions) || !in_array($item, $permissions)) {
            //当用户没有权限列表，而action设置了权限时 不通过
            throw new NoAuthorizeException("拒绝访问",403);
        }

        return true; 
    }
}
